feat(results): append-only run index for fast Studio list view#1260
Closed
christso wants to merge 1 commit into
Closed
feat(results): append-only run index for fast Studio list view#1260christso wants to merge 1 commit into
christso wants to merge 1 commit into
Conversation
…P1) Adds index/runs.jsonl to the results repo so Studio's /api/runs reads ONE file instead of readdir+statSync+loadResultFile per run (O(N) → O(1)). Changes: - RunIndexEntry interface (snake_case wire format): run_id, timestamp, experiment, target, test_count, passed, pass_rate, avg_score, size_bytes, tags, sha - appendToRunIndex / readRunIndex helpers in packages/core - directPushResults: writes index entry on each push; backfills commit sha via --amend after the initial commit - reindexResultsRepo: rebuilds index from scratch for migration - listMergedResultFiles: reads index/runs.jsonl first; falls back to directory walk for older repos without an index - agentv results reindex: CLI command to backfill existing repos (--dry-run) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Deploying agentv with
|
| Latest commit: |
f2d917a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://f1b2ce20.agentv.pages.dev |
| Branch Preview URL: | https://p1-runs-index.agentv.pages.dev |
Collaborator
Author
|
Closing — the index-file approach was solving the right problem the wrong way. Design pivotAfter deeper review (and comparing with entireio + skillfully patterns), the cleaner architecture is:
This removes:
A fresh PR will land the new architecture in one shot. Tracking issue #1259 will get a follow-up comment explaining how the P1-P6 breakdown collapses given the new design. |
This was referenced May 21, 2026
christso
added a commit
that referenced
this pull request
May 23, 2026
* docs: design plan for git-native results storage (#1259) Captures the agreed architecture before implementation: - Git is the canonical store; local clone is the working copy - No separate index file — git tree IS the index - Eval writes directly to clone working tree (not project-local .agentv/results/) - Reads via git ls-tree + git cat-file --batch (no checkout) - Pagination via cursor - mode: github explicit in config (extension point) Supersedes closed PR #1260. See docs/plans/git-native-results.md for full design. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(results): Pass 1 — config schema + path renames - Add `mode: 'github'` as required field to ResultsConfig - Repurpose `results.path` as optional local filesystem path for clone (default: ~/.agentv/results/<slug>/); reject old-style subdir values (e.g. 'runs') with a migration message - Rename ResultsRepoCachePaths → ResultsRepoLocalPaths - Rename getResultsRepoCachePaths → getResultsRepoLocalPaths - Rename cache_dir → local_dir in ResultsRepoStatus wire format - normalizeResultsConfig: fill default path, expand ~, include mode - Remove redundant local normalizeResultsConfig copy in remote.ts - Update config-validator.ts to enforce mode and filesystem-path rule - Update tests for new schema Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(results): fix lint + update resolveResultsRepoRunsDir + serve tests - Fix biome string-concat lint error (single template literal) - resolveResultsRepoRunsDir: use normalized.path directly (new design) - getResultsRepoStatus: check existsSync(normalized.path) for available, set local_dir to normalized.path - serve.test.ts: update two tests to use mode:github schema and new default path layout (~/.agentv/results/<slug>/runs/...) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * wip: initial git-native listing skeleton + implementation goal - Added listGitRuns() using git ls-tree + cat-file --batch - Improved batch parser - Saved implementation goal document This is early progress toward the full git-native results implementation. More to come in follow-up commits. * fix: remove duplicate execFileAsync declaration * feat(results): improve git-native listing metadata shape - Enrich GitListedRun with display_name, test_count, avg_score, size_bytes - Update remote.ts mapping to populate ResultFileMeta fields - Read path now returns data Studio can render * chore: update implementation goal + docker ownership fix - Add user: ${UID}:${GID} to docker-compose for mounted repo permissions - Update goal document with current status - Reinstall dependencies in worktree * fix(results): restore git-native run listing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(results): satisfy lint Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(test): stabilize git subprocess checks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(test): satisfy lint and timeouts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(results): finish git-native results flow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(results): complete remote-only studio flow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * seed repo * fix(test): isolate git env in serve regression Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(test): restore readme after temp repo setup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(test): trim low-value flaky coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(results): materialize synced remote runs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(results): atomically materialize synced runs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(studio): clarify remote results behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(cli): treat AGENTV_HOME log as info Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(studio): refresh remote results screenshots Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Test User <test@example.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements P1 of #1259 — adds an append-only
index/runs.jsonlto the results repo so Studio's/api/runsreads one file instead ofreaddir+statSync+loadResultFileper run.Index format
Each line in
index/runs.jsonlis a JSON object:{"run_id":"myexp::2026-05-21T10-00-00-000Z","timestamp":"2026-05-21T10:00:01.000Z","experiment":"myexp","target":"gpt-4o","test_count":5,"passed":4,"pass_rate":0.8,"avg_score":0.85,"size_bytes":12345,"tags":[],"sha":"abc123def"}shais the git commit SHA of the results-repo commit that added the run. It is backfilled viagit commit --amend --no-editimmediately after the initial commit (before the push).How reads change
listMergedResultFiles(called by/api/runsevery 5s) now:index/runs.jsonlin the cached results repo → if present, reads it as a single file (O(1))listResultFilesFromRunsDir(directory walk) if the index is missing — old repos keep workingHow writes change
directPushResults(called onauto_push) now accepts an optionalindexEntry. When provided:index/runs.jsonlgit rev-parse HEAD, patches the last index line with the sha--no-edit)Migration command
Walks the existing run tree, rebuilds
index/runs.jsonlfrom scratch, commits and pushes. Run once after upgrading; new pushes maintain the index automatically.Test plan
packages/core/test/evaluation/run-index.test.ts— 8 tests: append creates dirs, writes valid JSONL, appends without overwriting, sha round-trip, read handles missing/malformed filesapps/cli/test/commands/results/remote.test.ts— 5 tests: encode/decode/identify remote run IDs, index parse correctness, fallback when index absentbun --filter @agentv/core test— 1782 pass, 0 failbun --filter agentv test— 553 pass, 0 failbun --filter @agentv/core typecheck— cleanbun --filter agentv typecheck— cleanbun run lint— cleanCloses part of #1259 (P1 sub-task).
🤖 Generated with Claude Code